home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Newswatcher 2.0b22 / NW Source / Source / strutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-02  |  9.5 KB  |  349 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     strutil.c
  4.  
  5.     This reusable module contains miscellaneous string handling 
  6.     utility routines.
  7.     
  8.     Copyright © 1994, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "def.h"
  16. #include "strutil.h"
  17. #include "memutil.h"
  18.  
  19.  
  20.  
  21. /* This table maps characters together for a case and diacritical 
  22.    insensitive comparison, using the Mac 8 bit international character set. */
  23.  
  24. static unsigned char gTable[256] = {
  25.     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  26.     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
  27.     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
  28.     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  29.     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
  30.     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
  31.     0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
  32.     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
  33.     0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45,
  34.     0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55,
  35.     0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0x4F,
  36.     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xAE, 0x4F,
  37.     0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0x22, 0x22, 0xC9, 0x20, 0x41, 0x41, 0x4F, 0xAE, 0xAE,
  38.     0xD0, 0xD1, 0x22, 0x22, 0x27, 0x27, 0xD6, 0xD7, 0x59, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
  39.     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
  40.     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
  41. };
  42.  
  43.  
  44.  
  45. /*----------------------------------------------------------------------------
  46.     MyStrEqual 
  47.     
  48.     Compare two strings, case and diacritical insensitive.
  49.             
  50.     Entry:    s1 = pointer to first C-format string.
  51.             s2 = pointer to second C-format string.
  52.             
  53.     Exit:    function result = true if strings are equal.
  54. ----------------------------------------------------------------------------*/
  55.  
  56. Boolean MyStrEqual (char *s1, char *s2)
  57. {
  58.     unsigned char *t = gTable;
  59.     unsigned char *us1 = (unsigned char*)s1;
  60.     unsigned char *us2 = (unsigned char*)s2;
  61.  
  62.     while (t[*us1] == t[*us2++])
  63.         if (*us1++ == 0) return true;
  64.     return false;
  65. }
  66.  
  67.  
  68.  
  69. /*----------------------------------------------------------------------------
  70.     MyStrNEqual 
  71.     
  72.     Compare the first n characters of two strings, case and diacritical 
  73.     insensitive.
  74.             
  75.     Entry:    s1 = pointer to first string.
  76.             s2 = pointer to second string.
  77.             n = number of characters to compare.
  78.             
  79.     Exit:    function result = true if equal.
  80. ----------------------------------------------------------------------------*/
  81.  
  82. Boolean MyStrNEqual (char *s1, char *s2, short n)
  83. {
  84.     unsigned char *t = gTable;
  85.     unsigned char *us1 = (unsigned char *)s1;
  86.     unsigned char *us2 = (unsigned char *)s2;
  87.  
  88.     while (--n >= 0 && t[*us1++] == t[*us2++]) /* do nothing */;
  89.     return n < 0;
  90. }
  91.  
  92.  
  93.  
  94. /*----------------------------------------------------------------------------
  95.     MyNSubstringSearch 
  96.     
  97.     Do a case and diacritical insensitive substring search.
  98.             
  99.     Entry:    s1 = pointer to string to be searched.
  100.             s2 = pointer to search string, C-format.
  101.             s1len = length of s1.
  102.             giveTime = pointer to give time function, or nil if none.
  103.             
  104.     Exit:    function result = error code = userCanceledErr if
  105.                 giveTime != nil and search canceled by user, else
  106.                 noErr.
  107.             *offset = offset in s1 of first occurence of s2, or
  108.                 -1 if none found.
  109. ----------------------------------------------------------------------------*/
  110.  
  111. OSErr MyNSubstringSearch (char *s1, char *s2, long s1len, long *offset,
  112.     OSErr (*giveTime)(Boolean))
  113. {
  114.     unsigned char *t = gTable;
  115.     unsigned char *p, *q, *s1Start;
  116.     long n;
  117.     unsigned long tickLongTime;
  118.     Boolean longTime = false;
  119.     OSErr err = noErr;
  120.  
  121.     if (*s2 == 0) {
  122.         *offset = 0;
  123.         return noErr;
  124.     }
  125.     n = s1len - strlen(s2) + 1;
  126.     s1Start = (unsigned char*)s1;
  127.     tickLongTime = TickCount() + 30;
  128.     while (n-- > 0) {
  129.         p = (unsigned char*)s1;
  130.         q = (unsigned char*)s2;
  131.         while (t[*p] == t[*q]) {
  132.             q++;
  133.             if (*q == 0) {
  134.                 *offset = (unsigned char*)s1 - s1Start;
  135.                 return noErr;
  136.             }
  137.             p++;
  138.         }
  139.         s1++;
  140.         if (giveTime != nil && (n & 0xf) == 0) {
  141.             if (!longTime && TickCount() > tickLongTime) longTime = true;
  142.             if (longTime) {
  143.                 err = (*giveTime)(false);
  144.                 if (err != noErr) return err;
  145.             }
  146.         }
  147.     }
  148.     *offset = -1;
  149.     return noErr;
  150. }
  151.  
  152.  
  153.  
  154. /*----------------------------------------------------------------------------
  155.     MySubstringSearch 
  156.     
  157.     Do a case and diacritical insensitive substring search.
  158.             
  159.     Entry:    s1 = pointer to string to be searched, C-format.
  160.             s2 = pointer to search string, C-format.
  161.             giveTime = pointer to give time function, or nil if none.
  162.             
  163.     Exit:    function result = error code = userCanceledErr if
  164.                 giveTime != nil and search canceled by user, else
  165.                 noErr.
  166.             *offset = offset in s1 of first occurence of s2, or
  167.                 -1 if none found.
  168. ----------------------------------------------------------------------------*/
  169.  
  170. OSErr MySubstringSearch (char *s1, char *s2, long *offset,
  171.     OSErr (*giveTime)(Boolean))
  172. {
  173.     return MyNSubstringSearch (s1, s2, strlen(s1), offset, giveTime);
  174. }
  175.  
  176.  
  177.  
  178. /*----------------------------------------------------------------------------
  179.     MyNIsASubstring 
  180.     
  181.     Do a case and diacritical insensitive substring search.
  182.             
  183.     Entry:    s1 = pointer to string to be searched.
  184.             s2 = pointer to search string, C-format.
  185.             s1len = length of s1.
  186.             
  187.     Exit:    function result = true if s1 contains s2.
  188. ----------------------------------------------------------------------------*/
  189.  
  190. Boolean MyNIsASubstring (char *s1, char *s2, long s1len)
  191. {
  192.     long offset;
  193.  
  194.     MyNSubstringSearch (s1, s2, s1len, &offset, nil);
  195.     return offset != -1;
  196. }
  197.  
  198.  
  199.  
  200. /*----------------------------------------------------------------------------
  201.     MyIsASubstring 
  202.     
  203.     Do a case and diacritical insensitive substring search.
  204.             
  205.     Entry:    s1 = pointer to string to be searched, C-format.
  206.             s2 = pointer to search string, C-format.
  207.             
  208.     Exit:    function result = true if s1 contains s2.
  209. ----------------------------------------------------------------------------*/
  210.  
  211. Boolean MyIsASubstring (char *s1, char *s2)
  212. {
  213.     long offset;
  214.  
  215.     MyNSubstringSearch (s1, s2, strlen(s1), &offset, nil);
  216.     return offset != -1;
  217. }
  218.  
  219.  
  220.  
  221. /*----------------------------------------------------------------------------
  222.     MyIsASubstringHandle
  223.     
  224.     Do a case and diacritical insensitive substring search.
  225.             
  226.     Entry:    h = handle to text to be searched.
  227.             s2 = pointer to search string, C-format.
  228.             
  229.     Exit:    function result = true if s1 contains s2.
  230. ----------------------------------------------------------------------------*/
  231.  
  232. Boolean MyIsASubstringHandle (Handle h, char *s2)
  233. {
  234.     long len, offset;
  235.  
  236.     len = MyGetHandleSize(h);
  237.     MyNSubstringSearch (*h, s2, len, &offset, nil);
  238.     return offset != -1;
  239. }
  240.  
  241.  
  242.  
  243. /*----------------------------------------------------------------------------
  244.     CopyPascalString 
  245.     
  246.     Copy a pascal format string.
  247.             
  248.     Entry:    to = pointer to destination string.
  249.             from = pointer to source string.
  250. ----------------------------------------------------------------------------*/
  251.  
  252. void CopyPascalString (StringPtr to, StringPtr from)
  253. {
  254.     BlockMoveData(from, to, *from+1);
  255. }
  256.  
  257.  
  258.  
  259.  
  260. /*----------------------------------------------------------------------------
  261.     CrackNum 
  262.     
  263.     Crack a decimal number from a string after skipping white space.
  264.     
  265.     Entry:    *x = pointer to string.
  266.             
  267.     Exit:    function result = cracked number.
  268.             *x = pointer to first character following number in string.
  269. ----------------------------------------------------------------------------*/
  270.  
  271. long CrackNum (char **x)
  272. {    
  273.     long result = 0;
  274.     char *y;
  275.     
  276.     y = *x;
  277.     while (isLWSP(*y)) y++;
  278.     while (isdigit(*y)) {
  279.         result = 10*result + (*y - '0');
  280.         y++;
  281.     }
  282.     *x = y;
  283.     return result;
  284. }
  285.  
  286.  
  287.  
  288. /*----------------------------------------------------------------------------
  289.     GetCString 
  290.     
  291.     Get a C-format string from the STR# 128 resource.
  292.     
  293.     Entry:    index of string in STR# 128.
  294.             
  295.     Exit:    str = string.
  296. ----------------------------------------------------------------------------*/
  297.  
  298. void GetCString (short index, char *str)
  299. {
  300.     GetIndString((StringPtr)str, 128, index);
  301.     p2cstr((StringPtr)str);
  302. }
  303.  
  304.  
  305.  
  306. /*----------------------------------------------------------------------------
  307.     GetPString 
  308.     
  309.     Get a P-format string from the STR# 128 resource.
  310.     
  311.     Entry:    index of string in STR# 128.
  312.             
  313.     Exit:    str = string.
  314. ----------------------------------------------------------------------------*/
  315.  
  316. void GetPString (short index, StringPtr str)
  317. {
  318.     GetIndString(str, 128, index);
  319. }
  320.  
  321.  
  322.  
  323. /*----------------------------------------------------------------------------
  324.     GetEquivalentCharacters 
  325.     
  326.     Get all characters equivalent to a character under case and diacritical
  327.     insensitive comparison.
  328.     
  329.     Entry:    x = character.
  330.             
  331.     Exit:    equivs = C-format list of equivalent characters.
  332.             *numEquiv = number of equivalent characters.
  333. ----------------------------------------------------------------------------*/
  334.  
  335. void GetEquivalentCharacters (unsigned char x, unsigned char *equivs, short *numEquiv)
  336. {
  337.     unsigned char y;
  338.     unsigned char *p, *q;
  339.     short z;
  340.     
  341.     y = gTable[x];
  342.     q = equivs;
  343.     for (z = 0, p = gTable; z < 256; z++, p++) {
  344.         if (*p == y) *q++ = z;
  345.     }
  346.     *q = 0;
  347.     *numEquiv = q - equivs;
  348. }
  349.